import { FC, ReactElement, useEffect, useRef, useState } from "react";
import Input, { InputProps } from "../Input/input";
import useDebounceEffect from "../../hooks/useDebounceEffect";
import useClickOutside from "../../hooks/useClickOutside";

interface DataSourceObject {
    value: string;
}

/** 定义建议项的数据结构，用户可根据泛型自行定义，同时必须包含一个string类型的value值 */
export type DataSourceType<T = {}> = T & DataSourceObject;

export interface AutoCompleteProps extends Omit<InputProps, 'onSelect'> {
    /** 根据传入的值，匹配相应的建议项列表，匹配规则和数据由用户自行定义 */
    fetchSuggestions: (str: string) => DataSourceType[] | Promise<DataSourceType[]>;
    /** 选择建议项后的回调 */
    onSelect?: (item: DataSourceType) => void;
    /** 展示自定义模板 */
    renderOption?: (item: DataSourceType) => ReactElement;
}

const AutoComplete: FC<AutoCompleteProps> = (props) => {

    const {
        fetchSuggestions,
        onSelect,
        value = '',
        renderOption,
        ...restProps
    } = props;

    // 状态：输入值
    const [inputValue, setInputValue] = useState(value as string);

    // 状态：要展示的建议列表
    const [suggestions, setSuggestions] = useState<DataSourceType[]>([]);

    // 用于判断是否可以调用fetchSuggestions
    const isFetch = useRef(true);

    const refNode = useRef<HTMLDivElement>(null);

    // 功能3：当点击页面其他元素时，取消显示下拉菜单
    useClickOutside(refNode, () => {
        setSuggestions([]);
    });

    // 功能1：根据输入值，动态请求推荐列表（添加防抖功能）
    useDebounceEffect(() => {
        if (!isFetch.current) {
            return;
        }

        if (inputValue) {
            console.log('请求数据：' + inputValue);
            // 获取筛选后的数据列表
            const results = fetchSuggestions(inputValue);
            if (results instanceof Promise) {
                // 处理异步请求数据
                results.then(data => {
                    setSuggestions(data);
                })
            } else {
                setSuggestions(results);
            }
        } else {
            setSuggestions([]);
        }
    }, [inputValue], 300)

    // 更新输入值
    function handleValueChange(value: string) {
        setInputValue(value);
        isFetch.current = true;
    }

    // 功能2：点击推荐项，显示到输入框中
    function handleSelect(item: DataSourceType) {
        setInputValue(item.value);
        setSuggestions([]);
        isFetch.current = false;
    }


    // 根据推荐列表，生成下拉展示
    function generateDropdown() {
        if (suggestions.length === 0) {
            return null;
        }

        return (
            <ul>
                {suggestions.map((item, index) => {
                    return (
                        <li key={index} onClick={() => handleSelect(item)}>
                            {/* 如果用户传入自定义模版，则使用模板展示 */}
                            {renderOption ? renderOption(item) : item.value}
                            {/* {renderOption ? renderOption(item) : item} */}
                        </li>
                    )
                })}
            </ul>
        )
    }


    return (
        <div className="kd-auto-complete" ref={refNode}>
            <Input value={inputValue} onValueChange={handleValueChange} {...restProps} />
            {generateDropdown()}
        </div>
    )
}

export default AutoComplete;